home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- Author : Matthew Stroup
- Description: Amiga graphics output for v2600 Atari 2600 emulator
- Version : 2.0 Feb 5, 1997
- ******************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "types.h"
- #include "config.h"
- #include "vmachine.h"
- #include "colours.h"
- #include "keyboard.h"
- #include "options.h"
- #include "display.h"
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/display.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <hardware/custom.h>
- #include <hardware/cia.h>
-
- /*****************************************************************************/
-
- void __asm chunky2planar(register __a0 UBYTE *chunky, register __a1 PLANEPTR raster);
-
- void __asm c2p8_init ( register __a0 UBYTE *chunky, // pointer to chunky data
- register __a1 UBYTE *chunky_cmp, // pointer to chunky comparison buffer
- register __a2 PLANEPTR *planes, // pointer to planes
- register __d0 ULONG signals1, // 1 << sigbit1
- register __d1 ULONG signals2, // 1 << sigbit2
- register __d2 ULONG pixels, // WIDTH * HEIGHT
- register __d3 ULONG offset, // byte offset into plane
- register __d4 UBYTE *buff2, // Chip buffer (size = width*height)
- register __d5 UBYTE *buff3, // Chip buffer (size = width*height)
- register __a3 struct GfxBase *GfxBase);
-
- void __asm c2p8_go(void);
-
- long get_signals(void);
- void free_signals(void);
- long get_chunky_mem(void);
- void free_chunky_mem(void);
- void init_chunky(void);
- long get_window(void);
-
- UBYTE *chunky_cmp=0; // chunky data comparison buffer (preferably in fast ram)
- UBYTE *buff2=0; // blitter buffer (chip ram)
- UBYTE *buff3=0; // blitter buffer (chip ram)
-
- long sigbit1 = -1; // used by c2p8()
- long sigbit2 = -1; // used by c2p8()
-
- struct Screen *scr=0;
- struct Window *win=0;
- struct RastPort *rp=0, temprp;
- struct ViewPort *vp=0;
- struct IntuiMessage *message=0;
- struct GfxBase *GfxBase=0;
- struct IntuitionBase *IntuitionBase=0;
-
- struct TagItem TagArray[] = {
- // can add other tags here
- TAG_DONE,0
- };
-
- char perm[8] = {0, 1, 2, 3, 4, 5, 6, 7}; // bitplane order
-
- PLANEPTR raster=0, temprast=0; // 8 contiguous bitplanes
- struct BitMap bitmap_bm, tempbm; // The full depth-8 bitmap
-
- struct ExtNewScreen NewScreenStructure = {
- 0,0,
- 320,200,
- 7,
- 0,1,
- NULL,
- CUSTOMSCREEN+CUSTOMBITMAP+SCREENQUIET+NS_EXTENDED,
- NULL,
- NULL,
- NULL,
- &bitmap_bm,
- (struct TagItem *)&TagArray
- };
-
- struct NewScreen ns = {
- 0,0, // Left edge, Right edge
- 320,200,7, // Width, Height, Depth
- 1,2, // Detail pen, block pen
- SPRITES, // Display modes
- CUSTOMSCREEN, // Type
- NULL, // Font
- NULL, // Title
- NULL, // Gadgets
- NULL // Custom Bitmap
- };
-
- struct NewWindow NewWindowStructure1 = {
- 0,0,
- 320,200,
- 0,1,
- NULL,
- SIMPLE_REFRESH+BORDERLESS+NOCAREREFRESH,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- 0,0,
- 0,0,
- CUSTOMSCREEN
- };
-
- /* Start of image data */
- UBYTE *vscreen=0;
-
- /* The width and height of the image, including any magnification */
- int vwidth, vheight, theight;
-
- /* The frame rate counter. Used by the -rr switch */
- int tv_counter = 0;
-
- /* Optionally set by the X debugger. */
- int redraw_flag = 1;
-
- static int bytesize;
-
- long get_screen(void);
-
- UBYTE colors[NUMCOLS];
-
- extern int moudrv_x, moudrv_y, moudrv_but;
-
-
- #define CIAAPRA 0xBFE001
-
- struct CIA *ciamou = (struct CIA *) CIAAPRA;
-
- /*****************************************************************************/
-
- /* Turns on the television. */
- /* returns: 1 for success, 0 for failure */
- int tv_on (int argc, char **argv)
- {
- int i;
-
- // Make sure necessary ROM libraries are open
- IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0);
- if (IntuitionBase == NULL) return(0);
-
- GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0);
- if (GfxBase == NULL) return(0);
-
- if (Verbose) printf ("OK\n Allocating screen buffer...");
-
- vscreen = (UBYTE *) AllocMem (64000, MEMF_PUBLIC|MEMF_CLEAR);
-
- if (!vscreen)
- {
- if (Verbose) printf ("Memory Allocation FAILED\n");
- return (0);
- }
-
- if (base_opts.video==1)
- {
- if ((win=OpenWindowTags(NULL,
- WA_Title, "Amiga v2600",
- WA_AutoAdjust,TRUE,
- WA_InnerWidth, 320,
- WA_InnerHeight, 192,
- WA_DragBar, TRUE,
- WA_CloseGadget, TRUE,
- WA_DepthGadget,TRUE,
- WA_GimmeZeroZero, TRUE,
- WA_SmartRefresh, TRUE,
- WA_IDCMP,IDCMP_CLOSEWINDOW,
- TAG_DONE))==NULL) return(0);
-
- for (i=0; i<NUMCOLS; i++)
- {
- colors[i]=ObtainBestPen(win->WScreen->ViewPort.ColorMap,
- (colortable[i*2] & 0xff0000)<<8,
- (colortable[i*2] & 0x00ff00)<<16,
- (colortable[i*2] & 0x0000ff)<<24,
- OBP_Precision,PRECISION_EXACT,
- TAG_DONE);
- }
- rp=win->RPort;
- InitBitMap(&tempbm, 8, 320, 200);
- if ((temprast=(PLANEPTR)AllocRaster(320, 8*200))==NULL) return (0);
- for(i=0; i<8; i++)
- {
- tempbm.Planes[i] = temprast + (perm[i] * RASSIZE (320, 200));
- }
- InitRastPort(&temprp);
- temprp.BitMap=&tempbm;
- }
- else
- {
- if (get_screen()==0) return(0);
- ShowTitle(scr, 0);
- for (i=0; i<NUMCOLS; i++)
- {
- SetRGB32(&scr->ViewPort,i,
- (colortable[i*2] & 0xff0000)<<8,
- (colortable[i*2] & 0x00ff00)<<16,
- (colortable[i*2] & 0x0000ff)<<24);
- colors[i]=i;
- }
- if (base_opts.video==2)
- {
- if(get_chunky_mem()==0) return(0);
- if(get_signals())
- {
- NewWindowStructure1.Screen = scr;
- if (get_window()==0) return(0);
- // initialize c2p converter
- c2p8_init ( vscreen,
- chunky_cmp,
- &rp->BitMap->Planes[0],
- 1 << sigbit1,
- 1 << sigbit2,
- 64000,
- 0,
- buff2,
- buff3,
- GfxBase);
- }
- else return(0);
- }
- }
-
- bytesize = 64000;
-
- /* Calculate the video width and height */
- vwidth = tv_width * 2;
- theight = tv_height + 8;
- vheight = theight;
-
- /* Turn on the keyboard. Must be done after toplevel is created */
- init_keyboard();
-
- if (Verbose) printf ("OK\n\b");
- return (1);
- }
-
- /*****************************************************************************/
-
- /* Turn off the tv. Closes the X connection and frees the shared memory */
- void tv_off (void)
- {
- if (Verbose) printf ("Switching off...\n");
-
- if (base_opts.video==2)
- {
- free_chunky_mem();
- free_signals();
- }
-
- if (base_opts.video!=0)
- {
- if (win) CloseWindow(win);
- }
-
- if (base_opts.video==1)
- {
- if (temprast) FreeRaster (temprast, 320, 8*200);
- }
- else
- {
- if (scr) CloseScreen(scr);
- if (raster) FreeRaster (raster, 320, 8 * 200);
- }
-
- if (vscreen) FreeMem(vscreen, 64000);
- if (GfxBase) CloseLibrary((struct Library *)GfxBase);
- if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
- }
-
- /*****************************************************************************/
-
- /* Displays the tv screen */
- void tv_display (void)
- {
- /* Only display if the frame is a valid one. */
- if (tv_counter % base_opts.rr == 0)
- {
- switch(base_opts.video)
- {
- case 0:
- WaitBOVP(&scr->ViewPort);
- chunky2planar(vscreen,raster);
- break;
- case 1:
- WritePixelArray8(rp, 0, 0, 319, 191, vscreen, &temprp);
- if (message=(struct IntuiMessage *)GetMsg(win->UserPort))
- {
- if (message->Class==CLOSEWINDOW) exit(0);
- }
- break;
- case 2:
- c2p8_go();
- }
- }
- tv_counter++;
- }
-
- /*****************************************************************************/
-
- /* The Event code. */
- void tv_event (void)
- {
- read_keyboard();
- }
-
- /*****************************************************************************/
-
- UBYTE tv_color (UBYTE b)
- {
- return (UBYTE)(b >> 1);
- }
-
- /*****************************************************************************/
-
- long get_screen(void)
- {
- long depth, ok = 0;
-
- InitBitMap(&bitmap_bm, 8, 320, 200); // Full depth-8 bm
-
- // since c2p_020() needs 8 contiguous bitplanes, it is not
- // possible to just use OpenScreen() or AllocBitmap() as they
- // may give the bitplanes in a few chunks of memory (noncontiguous)
-
- if( raster = (PLANEPTR)AllocRaster (320, 8 * 200))
- {
- for(depth = 0; depth < 8; depth++)
- {
- bitmap_bm.Planes[depth] = raster + (perm[depth] * RASSIZE (320, 200));
- }
-
- if(scr = OpenScreen( (struct NewScreen *) &NewScreenStructure))
- {
- SetRast(&scr->RastPort, 0); // clear screen memory
- WaitBlit(); // wait until it's finished
-
- ok = 1;
- }
- }
-
- return(ok);
-
- }
-
- /*****************************************************************************/
-
- void free_chunky_mem(void)
- {
- if(buff3)
- FreeVec(buff3);
-
- if(buff2)
- FreeVec(buff2);
-
- if(chunky_cmp)
- FreeVec(chunky_cmp);
- }
-
- /*****************************************************************************/
-
- void free_signals(void)
- {
- if(sigbit1 != -1)
- {
- Wait (1 << sigbit1); // wait for last c2p8 to finish pass 3
- FreeSignal(sigbit1);
- sigbit1 = -1;
- }
-
- if(sigbit2 != -1)
- {
- Wait (1 << sigbit2); // wait for last c2p8 to finish totally
- FreeSignal(sigbit2);
- sigbit2 = -1;
- }
- }
-
- /*****************************************************************************/
-
- long get_chunky_mem(void)
- {
- if((chunky_cmp = AllocVec(64000, MEMF_CLEAR+MEMF_ANY))==0) return (0);
- if((buff2 = AllocVec(64000, MEMF_CLEAR+MEMF_CHIP))==0) return (0);
- if((buff3 = AllocVec(64000, MEMF_CLEAR+MEMF_CHIP))==0) return (0);
- return(1);
- }
-
- /*****************************************************************************/
-
- long get_signals(void)
- {
- long ok = 0;
-
- if(-1 != (sigbit1 = AllocSignal(-1)))
- {
- SetSignal (1 << sigbit1, 1 << sigbit1); // Initial state is "finished"
-
- if(-1 != (sigbit2 = AllocSignal(-1)))
- {
- SetSignal (1 << sigbit2, 1 << sigbit2); // Initial state is "finished"
-
- ok = 1;
- }
- }
-
- return(ok);
-
- }
-
- /*****************************************************************************/
-
- long get_window(void)
- {
- long ok = 0;
-
- if (win = OpenWindow(&NewWindowStructure1))
- {
- rp = win->RPort;
- ok = 1;
- }
-
- return(ok);
-
- }
-
- /*****************************************************************************/
-
- void moudrv_read(void)
- {
- moudrv_x=win->MouseX;
- moudrv_y=win->MouseY;
- moudrv_but=!(ciamou->ciapra & 0x0040);
- }
-
- void moudrv_init(void)
- {
- }
-
- void moudrv_update(void)
- {
- }
-
- void moudrv_close(void)
- {
- }
-